(*   def f (x)  =  *)
(*   print_string ("["^string_of_int(x)^"] "); flush stdout; *)
(*   reply x*x to f  *)
    
(*     def update (l) =      *)
(*   reply (List.iter (fun x -> set := x :: !set) l; true) to update *)
    
(* let wait =  *)
(*   def x () & y () = reply to x *)
(*    in x  *)

(* let main = *)
(*   Join.Ns.register Join.Ns.here "square" f;   *)
(*   Join.Ns.register Join.Ns.here "update_set" update ; *)

(*    Join.Site.listen (Unix.ADDR_INET (Join.Site.get_local_addr(), 12345)); *)
(*    wait()  *)


let hosts = ["clyte"; "coccinelle"; "pou"; "doryphore"; "hanneton";
 	     "cucullie"; "taon"; "sirex"; "termite"; "fourmi"; "bousier";
	     "cafard"; "blatte"; "luciole"; "scolopendre"; "mante";
	     "chenille"; "cancrelat"]
  
(* let hosts = ["mante"; "hanneton"] *)
  
let prog = "/info/master2/bozman/M2/prog_comparee/projet/src/run"
  
let available_hosts all_hosts = 
  let rec aux accu = function
    | [] -> accu
    | x :: xs ->
	Mlib.debug "  Checking host %11s... " x; flush stderr;
	match Unix.system ("ping -W 100 -c 1 " ^ x ^ " > /dev/null") with
	  | Unix.WEXITED i ->
	      if i <> 0 then let _ = Mlib.debug "[Unavaible]\n" in aux accu xs
	      else let _ =  Mlib.debug "[Available]\n" in aux (x :: accu) xs
	  | _ -> aux accu xs
  in
    aux [] all_hosts
      
let run_cmd cmd host index np =
  match Unix.fork () with
    | 0 -> 
	Mlib.debug "Starting to distribute ... %d %d \n" index np; 
	(* let qs = List.map string_of_int q in *)
	(* let qos = String.concat ", " qs in *)
	(* Printf.printf "ssh -f %s %s %d %d" host cmd index np; *)
	(* Unix.execvp "touch" [|"touch"; "."|] *)
	Unix.execvp "ssh" [|"ssh"; (* "-f"; *) host; cmd; string_of_int index;
	  		    string_of_int np|]
    | _ -> ()

let start ql ahh n =
  let count = ref 0 in
  assert (List.length ql = List.length ahh);
  let rec aux ql l = 
    match ql, l with
      | [], [] -> ()
      | q :: qs, host :: hosts ->	  
	  let index = !count * n in
	    incr count;
	  let nb_page = List.length q in
	    run_cmd prog host index nb_page;
	  aux qs hosts
      | _ -> assert false
  in
    aux ql ahh

let _ =

  let in_ch = Mlib.open_in_file Mlib.offsets_list in
  let lpos : int list =
    match Mlib.read_value in_ch with None -> [] | Some l -> l 
  in
    (*XXCAGO TODO: fragmenter lpos pour nb-machines*)
  let _ = Mlib.debug "Checking hosts ...\n"in
  let ahh = available_hosts hosts in      
    
  let nb_machines = List.length ahh in
  let _ = Mlib.debug "Available machine(s)... %d\n" nb_machines in

  let nb_pos = List.length lpos in
  let _ =  Mlib.debug "Number of wiki page(s)... %d\n" nb_pos in
    
  let nb_q = nb_pos / nb_machines in
  let _ = Mlib.debug "Number of wiki page / machine... %d\n" nb_q in
    
  let ql = Mlib.partition nb_q lpos in    
    start ql ahh nb_q
